package com.usian.config;

import com.usian.ElasticsearchApp;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.io.IOException;

@SpringBootTest(classes = {ElasticsearchApp.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class Test {
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private SearchRequest searchRequest;

    @Before
    public void getsearchRequest(){
        SearchRequest searchRequest = new SearchRequest("java2002");
    }

    public void getResponse(SearchResponse searchResponse){
        // 执行搜索
        SearchHit[] hits = searchResponse.getHits().getHits();

        for(int i =0;i<hits.length;i++){
            SearchHit hit = hits[i];
            System.out.println("查询所有结果"+hit);
        }
    }

    //创建索引库
    @org.junit.Test
    public void testCreateIndex() throws IOException {
        //创建“创建索引请求”对象，并设置索引名称
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("java2002");
        //设置索引参数
        createIndexRequest.settings(Settings.builder().put("number_of_shards",2).
                put("number_of_replicas",0));
        createIndexRequest.mapping("user", "{\n" +
                "  \"_source\": {\n" +
                "    \"excludes\":[\"description\"]\n" +
                "  }, \n" +
                " \t\"properties\": {\n" +
                "      \"name\": {\n" +
                "          \"type\": \"text\",\n" +
                "          \"analyzer\":\"ik_max_word\",\n" +
                "          \"search_analyzer\":\"ik_smart\"\n" +
                "      },\n" +
                "      \"description\": {\n" +
                "          \"type\": \"text\",\n" +
                "          \"analyzer\":\"ik_max_word\",\n" +
                "          \"search_analyzer\":\"ik_smart\"\n" +
                "       },\n" +
                "       \"studymodel\": {\n" +
                "          \"type\": \"keyword\"\n" +
                "       },\n" +
                "       \"price\": {\n" +
                "          \"type\": \"float\"\n" +
                "       },\n" +
                "       \"pic\":{\n" +
                "\t\t   \"type\":\"text\",\n" +
                "\t\t   \"index\":false\n" +
                "\t    },\n" +
                "       \"timestamp\": {\n" +
                "      \t\t\"type\":   \"date\",\n" +
                "      \t\t\"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd\"\n" +
                "    \t }\n" +
                "  }\n" +
                "}", XContentType.JSON);
        //创建索引操作客户端
        IndicesClient indices = restHighLevelClient.indices();

        //创建响应对象
        CreateIndexResponse response =
                indices.create(createIndexRequest,RequestOptions.DEFAULT);
        //得到响应结果
        boolean acknowledged = response.isAcknowledged();
        System.out.println("是否创建成功-----"+acknowledged);
    }


    @org.junit.Test
    public void testDeleteIndex() throws IOException {
        //创建“删除索引请求”对象
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("java2002");
        //创建索引操作客户端
        IndicesClient indices = restHighLevelClient.indices();
        //创建响应对象
        DeleteIndexResponse deleteIndexResponse =
                indices.delete(deleteIndexRequest,RequestOptions.DEFAULT);
        //得到响应结果
        boolean acknowledged = deleteIndexResponse.isAcknowledged();
        System.out.println("是否删除成功-----"+acknowledged);
    }


    //添加文档
    @org.junit.Test
    public void testAddDocument() throws IOException {
        //创建“索引请求”对象：索引当动词
        IndexRequest indexRequest = new IndexRequest("java2002", "user", "3");
        indexRequest.source("{\n" +
                " \"name\":\"张三\",\n" +
                " \"gender\":\"男\",\n" +
                " \"hobby\":\"赌，毒\",\n" +
                " \"model\":\"普通员工\"\n" +
                "}", XContentType.JSON);
        IndexResponse indexResponse =
                restHighLevelClient.index(indexRequest,RequestOptions.DEFAULT);
        System.out.println("添加数据---"+indexResponse.toString());
    }

    //批量添加
    @org.junit.Test
    public void testBulkAddDocument() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.add(new IndexRequest("java2002", "user").source("{\"name\":\"王五\",\"gender\":\"男\",\"hobby\":\"吃，喝，赌\",\"model\":\"Hr\"}", XContentType.JSON));
        bulkRequest.add(new IndexRequest("java2002", "user").source("{\"name\":\"赵六\",\"gender\":\"男\",\"hobby\":\"吃，喝，赌，毒，嫖\",\"model\":\"董事长他爹\"}", XContentType.JSON));
        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
        System.out.println(bulkResponse.hasFailures());
    }


    //文档修改
    @org.junit.Test
    public void testUpdateDocument() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("java2002", "user", "YSXCFHcB8eBiHmOunJK1");
        updateRequest.doc("{\n" +
                " \"name\":\"尼古拉斯赵四\"\n" +
                "}", XContentType.JSON);
        UpdateResponse updateResponse =
                restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);
        DocWriteResponse.Result result = updateResponse.getResult();
        System.out.println(result);
    }


    //根据id删除文档
    @org.junit.Test
    public void testDelDocument() throws IOException {
        //删除索引请求对象
        DeleteRequest deleteRequest = new DeleteRequest("java2002","user","YCXCFHcB8eBiHmOunJK1");
        //响应对象
        DeleteResponse deleteResponse =
                restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
        System.out.println(deleteResponse.getResult());
    }


    //查询文档
    @org.junit.Test
    public void getDoc() throws IOException {
        GetRequest getRequest = new GetRequest("java2002","user","1");
        GetResponse getResponse = restHighLevelClient.get(getRequest);
        boolean exists = getResponse.isExists();
        System.out.println(exists);
        String source = getResponse.getSourceAsString();
        System.out.println(source);
    }

    @org.junit.Test
    public void findAll() throws IOException {
        SearchRequest searchRequest = new SearchRequest("java2002");

        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());

        searchRequest.source(builder);

        SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);

        SearchHit[] hits = searchResponse.getHits().getHits();

        for(int i =0;i<hits.length;i++){
            SearchHit hit = hits[i];
            System.out.println("查询所有结果"+hit);
        }
    }

    //分页查询
    @org.junit.Test
    public void testSearchPage() throws IOException {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchSourceBuilder.from(1);
        searchSourceBuilder.size(2);
        searchSourceBuilder.sort("id", SortOrder.DESC);

        // 设置搜索源
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);

        this.getResponse(searchResponse);
    }

    @org.junit.Test
    public void testMatchQuery() throws Exception {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("name", "张").operator(Operator.AND));

        // 设置搜索源
        searchRequest.source(searchSourceBuilder);
        // 执行搜索
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
        this.getResponse(searchResponse);
    }

    @org.junit.Test
    public void testMultiMatchQuery() throws Exception {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery("张","name","hobby"));
        // 设置搜索源
        searchRequest.source(searchSourceBuilder);
        // 执行搜索
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
        this.getResponse(searchResponse);
    }



    @org.junit.Test
    public void testBooleanMatch() throws IOException {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //json条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("name","王"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("id").gte("2").lte(4));
        searchSourceBuilder.query(boolQueryBuilder);

        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(
                searchRequest, RequestOptions.DEFAULT);
        this.getResponse(searchResponse);
    }


    @org.junit.Test
    public void testFilterQuery() throws IOException {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("name","赵"));
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("id").gte(1).lte(3));
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
        this.getResponse(searchResponse);
    }

}